Conversation
…ements Features: - iCloud shared album sync: two-step API (webstream + webasseturls), handles 330 redirects, picks best derivative by pixel dimensions (handles iPhone 15 Pro key '2049'), filters videos, checksum sidecar files for upgrade detection - Embedded web settings server on port 8080 with full settings form and sync controls; web UI save now also writes to SharedPreferences so BootReceiver picks up changes without requiring an app restart - Geocoding now shows city only (not City, State, Country); cache key bumped to v2 to invalidate old entries - Photo info overlay: added XSmall (22px) text size option (default); for bottom positions city is shown above date; for top positions date stays on top - Slide duration change now takes effect immediately without waiting for the current timer to expire - Boot autostart: BootReceiver uses AlarmManager (setExactAndAllowWhileIdle) to schedule MainActivity launch 3s after boot; logs upgraded to Log.i so they appear in release builds
- Sync timeout is now configurable (15–120s, default 60s) in both the in-app settings and web UI; passed through to iCloud sync service so slow connections don't fail with the old 30s hard-coded limit - Auto-sync now fires on every save when a source is configured, not only when the URL changes — so tapping Save always kicks off a sync - Wi-Fi Settings shortcut added to Android section of settings screen (opens system Wi-Fi page via MethodChannel) - Device IP/web UI URL banner shown at top of settings screen - Web UI save now calls syncFromConfig so autostart SharedPreferences are updated immediately without requiring an app restart - BootReceiver logs upgraded to Log.i so they appear in release builds - Add FRAME_SETUP.md with quick ADB commands for setting up a new frame
Fixes a metrics-endpoint bug that could starve a low-end frame of CPU: - WebServerService._refreshProcessStatus() walked /proc/[0-9]*/cmdline in a shell loop, forking two processes per PID (~520 per scan on the PX-110). Replaced with a single `su 0 ps -A -o NAME` - The throttle timestamp was assigned after the await with no in-flight guard, so one slow scan let every later scrape start another 520-fork scan on top of the stuck one. Timestamp is now set up front, a 10s timeout bounds the call, and an in-flight flag allows only one scan - On 2026-09-19 this pile-up, together with an ActivityManager respawn loop, wedged system_server for eight hours: an orphaned `tr` was found spinning at 100% of a core Also adds FRAMEO.md coverage for the Pexar Frame PX-110 (MediaTek MT8167) that replaced the retired Frameo 106K: - Vendor install lock: the ROM blocks sideloading while ro.vendor.custom_recover is 1. The value is byte 0x3FE of the proinfo partition, published by nvram_daemon. Clearing it unblocks installs without touching the verity-protected system partition - Stock service survey. Never pm disable-user a package marked android:persistent="true" on this ROM — that is what caused the respawn loop. Disable the components instead and leave the package enabled - 32-bit only (armeabi-v7a); an arm64-only APK will not install - Build note: Flutter picks Android Studio's OpenJDK 25 JBR, which Gradle 8.14 cannot parse. Point --jdk-dir at Temurin 21 - Pinning the app as default HOME, and the outage post-mortem Ignores /backups/, which holds raw partition dumps containing the device serial and MAC address.
The Frameo 106K is retired, so its tooling and notes were mostly dead weight. - Delete scripts/fix-frameo.sh. It hardcoded the 106K's serial and IP, stopped a Rockchip memtrack HAL that does not exist on the PX-110, and disabled a package list that no longer matches - Add scripts/px110.sh: idempotent setup and health check. Connects over Wi-Fi (falling back to USB and re-enabling TCP mode), repairs the stock-service config, pins the app as default launcher, and reports health. --health reports without changing anything; --install deploys the APK after checking it has an armeabi-v7a slice - Restructure FRAMEO.md around the PX-110 as the current device and compress the 106K to what still transfers: the eMMC failure mode and how to map a bad sector to a file, the ADB factory reset, and why the two Rockchip-only app workarounds stay in the tree. 537 -> 313 lines - Drop the Wi-Fi/BT MAC from the notes. It is a stable hardware fingerprint with no operational use, and this repo has a public remote The script checks for the adups respawn loop and orphaned scan helpers specifically, since those are the two regressions that took the frame down.
Both existed for the retired Frameo 106K (RK3326) and are dead code on the Pexar PX-110: - stopCrashingMemtrackService() stopped a buggy RK3326 memtrack HAL. It was gated on Build.HARDWARE containing "rk" and on a vendor .so that does not exist here, so it never ran - warmEmmcFileCache() preloaded the 106K's failing system files into the page cache. Off by default and pointless on healthy storage. Removes the setting from the config interface, JSON store, runtime-settings sync, the Flutter settings screen and the web UI, plus EmmcCacheWarmService eMMC *monitoring* stays: opf_emmc_io_errors_total and _fetchEmmcIoErrors() are device-independent, and are what ruled out hardware failure during the 2026-09-19 outage. Also fixes two bugs in scripts/px110.sh found by running it: - `cmd | grep -q` under `set -o pipefail` reports failure even on a match, because grep -q exits early and SIGPIPEs the writer. This made the APK armeabi-v7a guard reject a valid APK. Capture output, then match - After --install the app relaunches and re-runs enableWifiAdb(), which does `stop adbd; start adbd` and kills the script's own connection, so every health check read as an empty failure. Wait and reconnect first
The settings server binds 0.0.0.0:8080 with Access-Control-Allow-Origin: * and had no authentication, so any host on the LAN could GET /api/config or /api/log. Both disclose the iCloud shared-album token, which is enough to open the album — and the wildcard CORS header meant any page a LAN user visited could read it too. - New web_ui_password config setting; empty preserves the old open behaviour - HTTP Basic auth on every route, checked with a constant-time comparison. Any username is accepted; only the password is verified - 401 responses carry WWW-Authenticate, so browsers prompt normally - Settable from the web UI and from the on-device settings screen. The on-device field is the escape hatch if the password is forgotten /metrics is deliberately exempt so Prometheus keeps scraping without credentials. It exposes only counters and gauges — no album URLs, tokens or log lines. Protecting it too means adding basic_auth to the scrape config. Verified on the frame: unauthenticated /api/config, /api/log, /api/status and / return 401 while /metrics returns 200; a wrong password returns 401; the correct one returns 200; and the album token is no longer retrievable without credentials. With no password set, all routes behave as before.
This is a public fork, so the frame's serial and IP should not be in it. - scripts/px110.sh now reads FRAME_SERIAL and FRAME_IP from scripts/frame.env, which is gitignored, and exits with guidance if they are unset. Environment variables still win over the file - Add scripts/frame.env.example as the template to copy - Replace the literal serial and IP in FRAMEO.md with $FRAME_SERIAL / $FRAME_IP, and drop the retired frame's serial from FRAME_SETUP.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Features: